package com.example.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.example.common.enums.OrderStatusEnum;
import com.example.common.enums.ResultCodeEnum;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.exception.CustomException;
import com.example.mapper.OrdersMapper;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 业务处理
 **/
@Service
public class OrdersService {

    private static final Logger log = LoggerFactory.getLogger(OrdersService.class);

    @Resource
    private OrdersMapper ordersMapper;
    @Resource
    private CartService cartService;
    @Resource
    private OrdersItemService ordersItemService;
    @Resource
    private DeliveryService deliveryService;

    /**
     * 新增
     */
    public void add(Orders orders) {
        ordersMapper.insert(orders);
    }

    /**
     * 删除
     */
    @Transactional
    public void deleteById(Integer id) {
//        删除的时候不仅要删除orders表的记录 还要删除ordersItem表的记录
        ordersMapper.deleteById(id);
        ordersItemService.deleteByOrderId(id);
    }

    /**
     * 批量删除
     */
    public void deleteBatch(List<Integer> ids) {
        for (Integer id : ids) {
            this.deleteById(id);
        }
    }

    /**
     * 修改
     */
    public void updateById(Orders orders) {
        Orders orders1 = this.selectById(orders.getId());
//        支付完后设置一个支付的时间
        if(OrderStatusEnum.NO_SEND.getValue().equals(orders.getStatus())){
            orders.setPayTime((DateUtil.now()));
        }
//        送达后设置一个送达时间
        if(OrderStatusEnum.NO_RECEIVE.getValue().equals(orders.getStatus())){
            orders.setArriveTime((DateUtil.now()));
        }
//        接单时验证状态
        if(OrderStatusEnum.IN_TRANSIT.getValue().equals(orders.getStatus())){
            //当买家退款或者取消订单
            if(OrderStatusEnum.NO_PAY.getValue().equals(orders1.getStatus()) || OrderStatusEnum.CANCEL.getValue().equals(orders1.getStatus()))
                throw new CustomException(ResultCodeEnum.CANCEL);
            orders.setArriveTime((DateUtil.now()));
        }
//        商家发货后随机分配给一个在线的骑手
        if(OrderStatusEnum.NO_DELIVERY_RECEIVE.getValue().equals(orders.getStatus())){
            //当买家退款或者取消订单
            if(OrderStatusEnum.NO_PAY.getValue().equals(orders1.getStatus()) || OrderStatusEnum.CANCEL.getValue().equals(orders1.getStatus()))
                throw new CustomException(ResultCodeEnum.CANCEL);
            Delivery delivery = new Delivery();
            delivery.setStatus(1);
//            选出在线的骑手
            List<Delivery> deliveryList = deliveryService.selectAll(delivery);
            int num = deliveryList.size();
//            随机分给一个骑手
            int random = new Random().nextInt(num)+1; // 随机一个在线骑手数目的数字 1~此骑手
            int i = 1;
            for (Delivery delivery1 : deliveryList) {
                if(i == random)
                    orders.setDeliveryId(delivery1.getId());
                i++;
            }
        }
        ordersMapper.updateById(orders);
    }

    /**
     * 根据ID查询
     */
    public Orders selectById(Integer id) {
        return ordersMapper.selectById(id);
    }

    /**
     * 查询所有
     */
    public List<Orders> selectAll(Orders orders) {
        //拿到当前用户的信息
        Account currentUser = TokenUtils.getCurrentUser();
        String role = currentUser.getRole();
        if(RoleEnum.BUSINESS.name().equals(role)){//如果是商家则只能查询自己商铺的类别
            orders.setBusinessId(currentUser.getId());//自己的id作为查询条件
        }
        if(RoleEnum.DELIVERY.name().equals(role)){//如果是骑手则只能查询自己的单
            orders.setDeliveryId(currentUser.getId());//自己的id作为查询条件
            return ordersMapper.selectDeliveryAll(orders);
        }
        return ordersMapper.selectAll(orders);
    }

    /**
     * 分页查询
     */
    public PageInfo<Orders> selectPage(Orders orders, Integer pageNum, Integer pageSize) {
        //拿到当前用户的信息
        Account currentUser = TokenUtils.getCurrentUser();
        String role = currentUser.getRole();
        if(RoleEnum.BUSINESS.name().equals(role)){//如果是商家则只能查询自己商铺的类别
            orders.setBusinessId(currentUser.getId());//自己的id作为查询条件
        }
        if(RoleEnum.DELIVERY.name().equals(role)){//如果是骑手则只能查询自己的单
            orders.setDeliveryId(currentUser.getId());//自己的id作为查询条件
            PageHelper.startPage(pageNum, pageSize);
            return PageInfo.of(ordersMapper.selectDeliveryAll(orders));
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Orders> list = ordersMapper.selectAll(orders);
        return PageInfo.of(list);
    }

    /**
     * 前台用户下单
     */
    @Transactional
    public void addOrder(OrdersDTO ordersDTO) {
        Integer businessId = ordersDTO.getBusinessId();
        Account currentUser = TokenUtils.getCurrentUser();
        Integer userId = currentUser.getId();
        if (userId == null) {
            //未登录，无权限下单
            throw new CustomException(ResultCodeEnum.NO_AUTH);
        }
        List<Cart> cartList = cartService.selectUserCart(currentUser.getId(), businessId);
        if (CollUtil.isEmpty(cartList)) {
            throw new CustomException(ResultCodeEnum.NO_GOODS);
        }
        Orders orders = new Orders();
        orders.setBusinessId(businessId); //商家
        String now = DateUtil.now(); //时间
        orders.setTime(now);
        orders.setPayType(ordersDTO.getPayType()); //支付方式
        orders.setUserId(userId);
        orders.setAddress(ordersDTO.getAddress()); //地址
        orders.setUser(ordersDTO.getUser()); //用户
        orders.setPhone(ordersDTO.getPhone()); //电话
        orders.setComment(ordersDTO.getComment()); //备注

        // 设置商品信息
        AmountDTO amountDTO = cartService.calc(userId, businessId);
        orders.setAmount(amountDTO.getAmount());
        orders.setDiscount(amountDTO.getDiscount());
        orders.setActual(amountDTO.getActual());

        // 得到购物车商品的总数
        Integer nums = cartList.stream().map(Cart::getNum).reduce(Integer::sum).orElse(0);
        orders.setName(cartList.get(0).getGoods().getName() + "等" + nums + "件商品");
        orders.setCover(cartList.get(0).getGoods().getImg());

        // 最后设置一个订单编号
        orders.setOrderNo(IdUtil.getSnowflakeNextIdStr());  // 雪花算法生成唯一的ID作为订单号
        // 设置订单状态
        orders.setStatus(OrderStatusEnum.NO_PAY.getValue());
        this.add(orders);

        // 再设置订单的 详细信息
        for (Cart cart : cartList) {
            OrdersItem ordersItem = new OrdersItem();
            ordersItem.setOrderId(orders.getId());
            ordersItem.setGoodsName(cart.getGoods().getName());
            ordersItem.setGoodsImg(cart.getGoods().getImg());
            ordersItem.setPrice(cart.getGoods().getActualPrice());
            ordersItem.setNum(cart.getNum());
            ordersItem.setGoodsId(cart.getGoodsId());
            ordersItem.setCategoryId(cart.getCategoryId());
            ordersItemService.add(ordersItem);
        }
        // 清空购物车
        cartService.deleteByBusiness(businessId, userId);
        //定时调用，15min未支付则取消
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @SneakyThrows
            public void run() {
                Date now = new Date();
                SimpleDateFormat lsdStrFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Orders orders = new Orders();
                orders.setStatus(OrderStatusEnum.NO_PAY.getValue());
                List<Orders> ordersList = ordersMapper.selectAll(orders);
                for (Orders orders1 : ordersList) {
                    if(OrderStatusEnum.NO_PAY.getValue().equals(orders1.getStatus())) {
                        Date time = lsdStrFormat.parse(orders1.getTime());
                        long diff = (now.getTime() - time.getTime()) / 1000;
                        if (diff >= 15*60) {
                            orders1.setStatus(OrderStatusEnum.CANCEL.getValue());
                            ordersMapper.updateById(orders1);
                        }
                    }
                }
            }
        }, 25*60*1000);
    }



    public List<Orders> selectUsageByBusinessId(Integer id) {
        return ordersMapper.selectUsageByBusinessId(id);
    }
}